Chapter 5.1 - Introduction to convnets


In [1]:
# Instatiating a small convolutional neural network
from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D


Using TensorFlow backend.

In [2]:
model = Sequential()
model.add(Conv2D(filters = 32, 
                 kernel_size = (3, 3), 
                 activation = 'relu', 
                 input_shape = (28, 28, 1)))
model.add(MaxPooling2D(pool_size = (2, 2)))
model.add(Conv2D(filters = 64, 
                 kernel_size = (3, 3), 
                 activation ='relu'))
model.add(MaxPooling2D(pool_size = (2, 2)))
model.add(Conv2D(filters = 64, 
                 kernel_size = (3, 3), 
                 activation = 'relu'))

In [3]:
# Prompting summary of the model
model.summary()


_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d_1 (Conv2D)            (None, 26, 26, 32)        320       
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 13, 13, 32)        0         
_________________________________________________________________
conv2d_2 (Conv2D)            (None, 11, 11, 64)        18496     
_________________________________________________________________
max_pooling2d_2 (MaxPooling2 (None, 5, 5, 64)          0         
_________________________________________________________________
conv2d_3 (Conv2D)            (None, 3, 3, 64)          36928     
=================================================================
Total params: 55,744
Trainable params: 55,744
Non-trainable params: 0
_________________________________________________________________

In [4]:
from keras.layers import Dense, Flatten

In [5]:
# Adding classifier part of the model
model.add(Flatten())
model.add(Dense(units = 64, 
                activation = 'relu'))
model.add(Dense(units = 10, 
                activation = 'softmax'))

In [6]:
# Prompting summary of the model
model.summary()


_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d_1 (Conv2D)            (None, 26, 26, 32)        320       
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 13, 13, 32)        0         
_________________________________________________________________
conv2d_2 (Conv2D)            (None, 11, 11, 64)        18496     
_________________________________________________________________
max_pooling2d_2 (MaxPooling2 (None, 5, 5, 64)          0         
_________________________________________________________________
conv2d_3 (Conv2D)            (None, 3, 3, 64)          36928     
_________________________________________________________________
flatten_1 (Flatten)          (None, 576)               0         
_________________________________________________________________
dense_1 (Dense)              (None, 64)                36928     
_________________________________________________________________
dense_2 (Dense)              (None, 10)                650       
=================================================================
Total params: 93,322
Trainable params: 93,322
Non-trainable params: 0
_________________________________________________________________

Preparing the dataset

Input images


In [7]:
from keras.datasets import mnist

In [8]:
# Importing the dataset
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()

In [9]:
# Reshaping the dataset
train_images = train_images.reshape((60000, 28, 28, 1))
test_images = test_images.reshape((10000, 28, 28, 1))

In [10]:
# Changing type to one used by Keras
train_images = train_images.astype('float32')
test_images = test_images.astype('float32')

In [11]:
# Normalization
# The data has values from 0 to 255. 
# It is preferred that to be between 0 and 1.
train_images /= 255
test_images /= 255

Output labels


In [12]:
from keras.utils import to_categorical

In [13]:
train_labels[0]


Out[13]:
5

In [14]:
# One-hot enconding
train_labels = to_categorical(train_labels)
test_labels = to_categorical(test_labels)

In [15]:
train_labels[0]


Out[15]:
array([ 0.,  0.,  0.,  0.,  0.,  1.,  0.,  0.,  0.,  0.])

Training


In [16]:
# Compiling the network
model.compile(optimizer = 'rmsprop',
              loss = 'categorical_crossentropy',
              metrics = ['accuracy'])

In [17]:
# Training
model.fit(train_images, 
          train_labels, 
          epochs = 5, 
          batch_size = 64)


Epoch 1/5
60000/60000 [==============================] - 11s - loss: 0.1733 - acc: 0.9456    
Epoch 2/5
60000/60000 [==============================] - 9s - loss: 0.0444 - acc: 0.9864     
Epoch 3/5
60000/60000 [==============================] - 9s - loss: 0.0316 - acc: 0.9901     
Epoch 4/5
60000/60000 [==============================] - 9s - loss: 0.0234 - acc: 0.9927     
Epoch 5/5
60000/60000 [==============================] - 9s - loss: 0.0181 - acc: 0.9945     
Out[17]:
<keras.callbacks.History at 0x1fed0192f60>

Evalutation


In [18]:
test_loss, test_acc = model.evaluate(test_images, test_labels)


 9920/10000 [============================>.] - ETA: 0s

In [19]:
test_acc


Out[19]:
0.99250000000000005

The network improves the prediction (comparing to previous architectures) despite that it was trained for only 5 epochs.